// GradientCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "..\UVLight.h"
#include "GradientCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGradientCtrl

CGradientCtrl::CGradientCtrl(CPaintDC * pDC, CRect * rt)
{
	m_pDC = pDC;
	m_Rect = rt;

	m_bVertical = TRUE;
	m_cUp = GetSysColor(COLOR_ACTIVECAPTION);
	m_cDown = GetSysColor(COLOR_BTNFACE);
	
	hinst_msimg32 = LoadLibrary( "msimg32.dll" );
	m_bCanDoGradientFill = FALSE;
		
	if(hinst_msimg32)
	{
		m_bCanDoGradientFill = TRUE;		
		dllfunc_GradientFill = ((LPFNDLLFUNC1) GetProcAddress( hinst_msimg32, "GradientFill" ));
	}
}

CGradientCtrl::~CGradientCtrl()
{
	FreeLibrary( hinst_msimg32 );
}


BEGIN_MESSAGE_MAP(CGradientCtrl, CWnd)
	//{{AFX_MSG_MAP(CGradientCtrl)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CGradientCtrl message handlers
//this function will be used only if msimg32.dll library is not available
void CGradientCtrl::DrawGradRect(COLORREF cLeft, COLORREF cRight, BOOL a_bVertical)
{
	CRect stepR;					// rectangle for color's band
	COLORREF color;				// color for the bands
	float fStep;
	
	if(a_bVertical)
		fStep = ((float)m_Rect->Height())/255.0f;	
	else
		fStep = ((float)m_Rect->Width())/255.0f;	// width of color's band

	
	if(m_bCanDoGradientFill) //msimg32.dll library is loaded
	{
	
		TRIVERTEX rcVertex[2];
		rcVertex[0].x=m_Rect->left;
		rcVertex[0].y=m_Rect->top;
		rcVertex[0].Red=GetRValue(m_cUp)<<8;	// color values from 0x0000 to 0xff00 !!!!
		rcVertex[0].Green=GetGValue(m_cUp)<<8;
		rcVertex[0].Blue=GetBValue(m_cUp)<<8;
		rcVertex[0].Alpha=0x0000;
		rcVertex[1].x=m_Rect->right; 
		rcVertex[1].y=m_Rect->bottom;
		rcVertex[1].Red=GetRValue(m_cDown)<<8;
		rcVertex[1].Green=GetGValue(m_cDown)<<8;
		rcVertex[1].Blue=GetBValue(m_cDown)<<8;
		rcVertex[1].Alpha=0;
		
		GRADIENT_RECT rect;
		rect.UpperLeft=0;
		rect.LowerRight=1;
		
		// fill the area 
		dllfunc_GradientFill(*m_pDC,rcVertex,2,&rect,1, m_bVertical ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H);
	}
	else
	{
		for (int iOnBand = 0; iOnBand < 255; iOnBand++) 
		{
			// set current band
			if(a_bVertical)
			{
				SetRect(&stepR,
					m_Rect->left, 
					m_Rect->top+(int)(iOnBand * fStep),
					m_Rect->right, 
					m_Rect->top+(int)((iOnBand+1)* fStep));	
			}
			else
			{
				SetRect(&stepR,
					m_Rect->left+(int)(iOnBand * fStep), 
					m_Rect->top,
					m_Rect->left+(int)((iOnBand+1)* fStep), 
					m_Rect->bottom);	
			}
			
			// set current color
			color = RGB((GetRValue(cRight)-GetRValue(cLeft))*((float)iOnBand)/255.0f+GetRValue(cLeft),
				(GetGValue(cRight)-GetGValue(cLeft))*((float)iOnBand)/255.0f+GetGValue(cLeft),
				(GetBValue(cRight)-GetBValue(cLeft))*((float)iOnBand)/255.0f+GetBValue(cLeft));
			// fill current band
			m_pDC->FillSolidRect(stepR,color);
		}
	}
}

void CGradientCtrl::SetReverseGradient()
{
	COLORREF cTemp = m_cUp;
	m_cUp = m_cDown;
	m_cDown = cTemp;
}

void CGradientCtrl::SetGradient(COLORREF upColor, COLORREF downColor, BOOL dir)
{
//	CStatic::SetWindowText(a_lpstr);
	m_cUp = upColor;
	m_cDown = downColor;
	m_bVertical = dir;
	DrawGradRect(m_cUp, m_cDown, dir);
} 

void CGradientCtrl::SetGradient()
{
	DrawGradRect(m_cUp, m_cDown, m_bVertical);
}
